---
title: TypeScript
description: Как использовать встроенную поддержку Typescript в Astro
i18nReady: true
---

import Since from '~/components/Since.astro';
import PackageManagerTabs from '~/components/tabs/PackageManagerTabs.astro';
import Tabs from '~/components/tabs/Tabs.astro';

Astro по умолчанию поддерживает [TypeScript](https://www.typescriptlang.org/). Вы можете импортировать `.ts` и `.tsx` файлы в свой проект, писать Typescript код прямо внутри своих [Astro компонентов](/ru/basics/astro-components/#скрипт-компонента), и даже использовать [`astro.config.ts`](/ru/guides/configuring-astro/#the-astro-config-file) файл, если это необходимо.

Используя Typescript, вы можете предотвратить ошибки во время выполнения, описывая типы объектов и компонентов в коде. К примеру, если вы используете  Typescript для [типизации параметров(пропсов) компонента](#параметры-компонентов), то редактор выведет ошибку, если вы попытаетесь передать параметр, который компонент не принимает.

Чтобы пользоваться преимуществами Typescript, не обязательно писать код на нем в Astro проектах. Astro всегда воспринимает код компонентов как Typescript, и [расширение Astro для VSCode](/ru/editor-setup/) будет стараться определяться типы насколько это возможно, чтобы обеспечить автодополнение, показывать подсказки и ошибки в вашем редакторе.

Astro dev сервер не выполняет никакой проверки типов, но вы можете использовать [отдельный скрипт](#проверка-типов) для проверки ошибок типизации прямо из командной строки.

## Настройка

Стартовые проекты Astro добавляют `tsconfig.json` файл в ваш проект по умолчанию. Даже если вы не планируете использовать Typescript, не удаляйте его, потому что такие инструменты как Astro и VS Code с помощью него получают информацию о проекте. Некоторые функции (например импорт npm пакетов) поддерживаются не полностью без `tsconfig.json` файла. Если вы устанавливаете Astro вручную, не забудьте создать этот файл самостоятельно.

Astro поддерживает три расширяемых `tsconfig.json` шаблона: `base`, `strict` и `strictest`. Шаблон `base` обеспечивает поддержку современных возможностей JavaScript, а также используется в качестве основы для других шаблонов. Мы рекомендуем использовать `strict` или `strictest` шаблоны, если вы планируете писать Typescript код в своем проекте. Вы можете посмотреть и сравнить эти шаблоны на гитхабе в директории [astro/tsconfigs/](https://github.com/withastro/astro/blob/main/packages/astro/tsconfigs/).

Для наследования от одного из шаблонов используйте синтаксис [`extends`](https://www.typescriptlang.org/tsconfig#extends):

```json title="tsconfig.json"
{
  "extends": "astro/tsconfigs/base"
}
```

Кроме того, наши шаблоны включают в себя файл  `env.d.ts` внутри `src` директории для обеспечения [клиентских типов Vite](https://vitejs.dev/guide/features.html#client-types) в вашем проекте:

```typescript title="env.d.ts"
/// <reference types="astro/client" />
```

Если вы не используете VS Code, вы можете установить [Astro TypeScript плагин](https://www.npmjs.com/package/@astrojs/ts-plugin) для поддержки импортов `.astro` файлов из `.ts` файлов (что может быть полезно при переиспользовании).

<PackageManagerTabs>
  <Fragment slot="npm">
  ```shell
  npm install @astrojs/ts-plugin
  ```
  </Fragment>
  <Fragment slot="pnpm">
  ```shell
  pnpm add @astrojs/ts-plugin
  ```
  </Fragment>
  <Fragment slot="yarn">
  ```shell
  yarn add @astrojs/ts-plugin
  ```
  </Fragment>
</PackageManagerTabs>

Затем, добавьте код ниже в `tsconfig.json`:

```json title="tsconfig.json"
  "compilerOptions": {
    "plugins": [
      {
        "name": "@astrojs/ts-plugin"
      },
    ],
  }
```

Чтобы проверить, что плагин работает, создайте `.ts` файл и импортируйте Astro компонент в него. Если вы не увидите ошибок, то плагин работает корректно.

### UI фреймворки

Если ваш проект использует [UI фреймворк](/ru/guides/framework-components/), то вам может потребоваться дополнительная настройка в зависимости от фреймворка. Пожалуйста, проверьте документацию о работе Typescript вместе с вашим фреймворком для дополнительной информации. ([Vue](https://vuejs.org/guide/typescript/overview.html#using-vue-with-typescript), [React](https://react-typescript-cheatsheet.netlify.app/docs/basic/setup), [Preact](https://preactjs.com/guide/v10/typescript), [Solid](https://www.solidjs.com/guides/typescript))

## Импорт типов

По возможности используйте явный импорт и экспорт типов.

```js del={1} ins={2} ins="type"
import { SomeType } from './script';
import type { SomeType } from './script';
```

Таким образом, вы избежите крайних случаев, когда сборщик Astro попытается некорректно собирать импортированные типы, как если бы они были JavaScript файлом.

Вы можете настроить TypeScript на принудительный импорт типов в файле `.tsconfig`.

<Tabs sharedStore="typescript-version">
	<Fragment slot="tab.4.9">TypeScript ≤4.9</Fragment>
	<Fragment slot="tab.5.0">TypeScript ≥5.0</Fragment>

    <Fragment slot="panel.4.9">
    	Задайте ключу [`importsNotUsedAsValues`](https://www.typescriptlang.org/tsconfig#importsNotUsedAsValues) значение `"error"`. TypeScript будет проверять ваши импорты и сообщит вам, когда следует использовать `import type`. Эта настройка по умолчанию включена в наши шаблоны `strict` и `strictest`.

    ```json title="tsconfig.json" ins={3}
    {
      "compilerOptions": {
        "importsNotUsedAsValues": "error"
      }
    }
    ```
    </Fragment>
    <Fragment slot="panel.5.0">
    	Задайте ключу [`verbatimModuleSyntax`](https://www.typescriptlang.org/tsconfig#verbatimModuleSyntax) значение `true`. TypeScript будет проверять ваши импорты и сообщит вам, когда следует использовать `import type`.

    ```json title="tsconfig.json" ins={3}
    {
      "compilerOptions": {
        "verbatimModuleSyntax": true
      }
    }
    ```
    </Fragment>

</Tabs>

## Импорт алиасов

Astro поддерживает [импорт алиасов](/ru/guides/aliases/) которые вы определили в `tsconfig.json` & `jsconfig.json` `paths` конфигурации. [Прочитайте наш гайд](/ru/guides/aliases/) чтобы узнать больше.

```astro title="src/pages/about/nate.astro" "@components" "@layouts"
---
import HelloWorld from '@components/HelloWorld.astro';
import Layout from '@layouts/Layout.astro';
---
```

```json title="tsconfig.json" {5-6}
{
  "compilerOptions": {
    "baseUrl": ".",
    "paths": {
      "@components/*": ["src/components/*"],
      "@layouts/*": ["src/layouts/*"]
    }
  }
}
```

## Расширение `window` и `globalThis`

Если вы захотите добавить свойство к глобальному объекту, то это можно сделать добавив объявление global в файл `env.d.ts`:

```ts title="env.d.ts"
declare global {
  var myString: string;
  function myFunction(): boolean;
}

export {};
```

Это обеспечит типизацию `globalThis.myString` и `globalThis.myFunction`, а также `window.myString` и `window.myFunction`.

Обратите внимание, что `window` доступно только в коде на стороне клиента. Функция `globalThis` доступна как на стороне сервера, так и на стороне клиента, но ее значение на стороне сервера не будет передано клиенту.

Если вы хотите добавить свойство только для объекта `window`, создайте вместо `global` интерфейс `Window`:

```ts title="env.d.ts"
interface Window {
  myFunction(): boolean;
}
```

## Параметры компонентов

Astro поддерживает типизацию параметров(пропсов) компонентов с помощью TypeScript. Для типизации добавьте TypeScript интерфейс `Props` в frontmatter вашего компонента. Вы можете использовать выражение `export`, но это не обязательно. [Astro VSCode расширение](/ru/editor-setup/) будет автоматически искать интерфейс `Props` и обеспечивать соответствующую поддержку TS при использовании этого компонента внутри другого шаблона.

```astro title="src/components/HelloProps.astro" ins={2-5}
---
interface Props {
  name: string;
  greeting?: string;
}
const { greeting = 'Hello', name } = Astro.props;
---
<h2>{greeting}, {name}!</h2>
```

### Распространенные паттерны типизации пропсов

- Если ваш компонент не принимает пропсов или слотов, вы можете использовать `type Props = Record<string, never>`.

- Если ваш компонент должен передавать дочерние элементы в свой слот, вы можете явно указать это через `type Props = { children: any; };`.

## Утилиты типизации

<Since v="1.6.0" />

Astro предоставляет встроенные типы для распространенных паттернов типизации пропсов. Они доступны в `astro/types`.

### Встроенные HTML атрибуты

Astro предоставляет тип `HTMLAttributes` для проверки того, что в вашей разметке используются валидные HTML-атрибуты. Эти типы можно использовать для создания пропсов компонентов.

К примеру, если вы создаете компонент `<Link>`, вы можете добавить стандартные HTML атрибуты для тега `<a>` в тип пропсов вашего компонента.

```astro title="src/components/Link.astro" ins="HTMLAttributes" ins="HTMLAttributes<'a'>"
---
import type { HTMLAttributes } from 'astro/types'
// используйте `type`
type Props = HTMLAttributes<'a'>;
// или extends с `interface`
interface Props extends HTMLAttributes<'a'> {
  myProp?: boolean;
}
const { href, ...attrs } = Astro.props;
---
<a href={href} {...attrs}>
  <slot />
</a>
```

Также можно расширить стандартные JSX выражения для того, чтобы добавить нестандартные атрибуты с помощью переопределения пространства имен `astroHTML.JSX` в файле `.d.ts`.

```ts
// src/custom-attributes.d.ts

declare namespace astroHTML.JSX {
  interface HTMLAttributes {
    'data-count'?: number;
    'data-label'?: string;
  }
}
```

:::note
`astroHTML` глобально инжектирован в `.astro` компоненты. Чтобы использовать их в TypeScript файлах, используйте [triple-slash directive](https://www.typescriptlang.org/docs/handbook/triple-slash-directives.html):

```ts
/// <reference types="astro/astro-jsx" />

type MyAttributes = astroHTML.JSX.ImgHTMLAttributes;
```

:::

### Полиморфные типы

<Since v="2.5.0" />

Astro имеет хелпер, чтобы сделать проще создание компонентов, которые могут быть различными HTML элементами с полной безопасностью типов. Это может быть полезно для компонентов как `<Link>`, которые могут быть элементами `<a>` или `<button>` в зависимости от пропсов, переданных в него.

Пример ниже использует полностью типизированный полиморфный компонент, который может быть любым HTML элементом. [`HTMLTag`](#встроенные-html-атрибуты) тип используется для того, чтобы быть уверенным, что параметр `as` - это валидный HTML элемент.

```astro
---
import { HTMLTag, Polymorphic } from 'astro/types';

type Props<Tag extends HTMLTag> = Polymorphic<{ as: Tag }>;

const { as: Tag, ...props } = Astro.props;
---

<Tag {...props} />
```

### Определение типов `getStaticPaths()`

<Since v="2.1.0" />

Astro имеет хелперы для работы с типами, которые возвращаются из  [`getStaticPaths()`](/ru/reference/api-reference/#getstaticpaths) функции, которая используется для динамических путей.

Вы можете получить тип [`Astro.params`](/ru/reference/api-reference/#astroparams) с помощью `InferGetStaticParamsType` и тип [`Astro.props`](/ru/reference/api-reference/#astroprops) с помощью `InferGetStaticPropsType`:

```astro title="src/pages/posts/[...slug].astro" {2,14-15}
---
import { InferGetStaticParamsType, InferGetStaticPropsType, GetStaticPaths } from 'astro';

export const getStaticPaths = (async () => {
  const posts = await getCollection('blog');
  return posts.map((post) => {
    return {
      params: { slug: post.slug },
      props: { draft: post.data.draft, title: post.data.title },
    };
  });
}) satisfies GetStaticPaths;

type Params = InferGetStaticParamsType<typeof getStaticPaths>;
type Props = InferGetStaticPropsType<typeof getStaticPaths>;

const { slug } = Astro.params as Params;
//               			 ^? { slug: string; }
const { title } = Astro.props;
//                			^? { draft: boolean; title: string; }
---
```

## Проверка типов

Чтобы проверить ошибки в вашем проекте, пожалуйста убедитесь, что вы установили [Astro VS Code расширение](/ru/editor-setup/). Обратите внимание, что команды `astro start` и `astro build` соберут код с помощью esbuild, но не запустят проверку типов. Чтобы избежать сборки кода содержащего Typescript ошибки, измените команду "build" в `package.json` файле на следующую:

```json title="package.json" del={2} ins={3} ins="astro check && tsc --noEmit && "
  "scripts": {
    "build": "astro build",
    "build": "astro check && tsc --noEmit && astro build",
  },
```

:::note
`astro check` проверяет только `.astro` файлы и `tsc --noEmit` проверяет только `.ts` и `.tsx` файлы. Для проверки типов в Svelte и Vue файла, вы можете использовать [`svelte-check`](https://www.npmjs.com/package/svelte-check) и [`vue-tsc`](https://www.npmjs.com/package/vue-tsc) пакеты соответственно.
:::

📚 Подробнее о [импортах `.ts` файлов](/ru/guides/imports/#typescript) в Astro.
📚 Подробнее о [TypeScript конфигурации](https://www.typescriptlang.org/tsconfig/).

## Решение проблем

### Ошибки типизации при использовании нескольких JSX фреймворков

Проблема может возникнуть при использовании нескольких JSX фреймворков в одном проекте, так как каждый фреймворк требует различных, иногда конфликтующих настроек в `tsconfig.json`.

**Решение**: Установите ключу [`jsxImportSource`](https://www.typescriptlang.org/tsconfig#jsxImportSource) значение `react` (стандартное), `preact` или `solid-js` в зависимости от самого используемого фреймворка в проекте. Затем, используйте [pragma comment](https://www.typescriptlang.org/docs/handbook/jsx.html#configuring-jsx) внутри всех конфликтующих файлов других фреймворков.

Для стандартного значения `jsxImportSource: react`, следует использовать:

```jsx
// For Preact
/** @jsxImportSource preact */

// For Solid
/** @jsxImportSource solid-js */
```
